﻿using log4net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using 语文字帖.Models;

namespace 语文字帖.Controllers
{
    public class HomeController : Controller
    {
        private static readonly ILog log = LogManager.GetLogger("NETCoreRepository", typeof(string));

        private readonly ILogger<HomeController> _logger;

        public const string MODELFILENAME = "model.png";
        private Bitmap baseImage;
        private Graphics baseGraphics;

        /// <summary>
        /// 取得的学年
        /// </summary>
        private string AcademicYear
        {
            get
            {
                int year1, year2;
                //9月份之后必定是第二学期
                if (DateTime.Now.Month >= 9)
                {
                    year1 = DateTime.Now.Year;
                    year2 = DateTime.Now.Year + 1;
                }
                else
                {
                    //判断是否农历过年，过年后，就判断为第二学期
                    if (new ChineseLunisolarCalendar().GetYear(DateTime.Today) == DateTime.Today.Year)
                    {
                        year1 = DateTime.Now.Year;
                        year2 = DateTime.Now.Year + 1;
                    }
                    else
                    {
                        year1 = DateTime.Now.Year - 1;
                        year2 = DateTime.Now.Year;
                    }
                }

                return string.Format("{0}-{1}", year1, year2);
            }
        }

        /// <summary>
        /// 取得的学年和学期
        /// </summary>
        private string Semester
        {
            get
            {
                string sem;
                //9月份之后必定是第二学期
                if (DateTime.Now.Month >= 9)
                {
                    sem = "一";

                }
                else
                {
                    //判断是否农历过年，过年后，就判断为第二学期
                    if (new ChineseLunisolarCalendar().GetYear(DateTime.Today) == DateTime.Today.Year)
                    {
                        sem = "一";
                    }
                    else
                    {
                        sem = "二";
                    }
                }

                return string.Format("学年第{0}学期", sem);
            }
        }

        public Color COLOR_BLACK = Color.Black;
        public Color COLOR_GREY = Color.FromArgb(160, 160, 160);
        public FontFamily CHINESE_FONTFAMILY = new FontFamily("楷体");
        public FontFamily NUMBER_FONTFAMILY = new FontFamily("FigurineCB AriesSP");
        public FontFamily CHINESE_HEADER_FONTFAMILY = new FontFamily("文鼎CS中等線");
        public FontFamily NUMBER_HEADER_FONTFAMILY = new FontFamily("XB Tabriz");
        public Point SCHOOLYEAR_HEADER = new Point(3590, 224);
        public Point ACADEMICYEARANDSEMESTER_CHINESE_HEADER = new Point(2224, 232);
        public Point ACADEMICYEARANDSEMESTER_NUMBER_HEADER = new Point(1840, 220);
        public Point LOCATION_CONTEXT = new Point(439, 1115);
        public Point LOCATION_TITLE_1 = new Point(1220, 473);
        public Point LOCATION_TITLE_2 = new Point(1674, 473);
        public Point GAP_CONTEXT = new Point(311, 317);
        public int[] y_edit =
            {
                0,
                -5,
                -12,
                -17,
                -22,
                -27,
                -32,
                -37,
                -42,
                -47,
                -52,
                -57,
                -62,
                -67,
                -72,
                -77
            };

        public string strNo = "15";
        public string strTitle = "搭船的鸟";
        public string strContext = "搭亲父沙啦响羽翠嘴悄吞哦捕";

        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
        }

        public IActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// 绘制标题头
        /// </summary>
        /// <param name="grade"></param>
        private void DrawHeader(string grade = "4")
        {
            SolidBrush brush = new SolidBrush(Color.Black);
            Font headerfont_chs = new Font(CHINESE_HEADER_FONTFAMILY, 10F);
            Font headerfont_num = new Font(NUMBER_HEADER_FONTFAMILY, 9F);
            string gradestr = "三";
            if (grade == "3")
            {
                gradestr = "三";
            }
            else if (grade == "4")
            {
                gradestr = "四";
            }
            else if (grade == "5")
            {
                gradestr = "五";
            }
            else if (grade == "6")
            {
                gradestr = "六";
            }

            baseGraphics.DrawString(gradestr, headerfont_chs, brush, SCHOOLYEAR_HEADER);
            baseGraphics.DrawString(Semester, headerfont_chs, brush, ACADEMICYEARANDSEMESTER_CHINESE_HEADER);
            baseGraphics.DrawString(AcademicYear, headerfont_num, brush, ACADEMICYEARANDSEMESTER_NUMBER_HEADER);
        }


        public static ImageCodecInfo GetEncoder(ImageFormat format)
        {
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.FormatID == format.Guid)
                {
                    return codec;
                }
            }
            return null;
        }
        public IActionResult Privacy()
        {
            return View();
        }


        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }

        public ActionResult GetImage(string no, string title, string context, string grade)
        {
            log.DebugFormat("生成图片字帖，No：{0} Title：{1} Context：{2} Grade：{3}", no, title, context, grade);

            try
            {


                strNo = no;
                strTitle = title;
                strContext = context;
                string path1 = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "Image", MODELFILENAME);
                baseImage = new Bitmap(path1);
                baseGraphics = Graphics.FromImage(baseImage);
                if (strContext.Length > 16)
                {
                    strContext = strContext.Substring(0, 16);
                }

                DrawHeader(grade);
                DrawTitle();
                DrawContext();
                string basedir = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "output");
                if (!Directory.Exists(basedir))
                {
                    Directory.CreateDirectory(basedir);
                }

                string outputfile = Path.Combine(basedir, string.Format("{0}.png", DateTime.Now.ToString("yyyyMMddHHmmss")));
                new Bitmap(baseImage).Save(outputfile);
                FileStream fs = System.IO.File.OpenRead(outputfile);
                byte[] data = new byte[fs.Length];
                fs.Read(data, 0, (int)fs.Length);
                return File(data, "image/jpg");
            }
            catch (Exception e)
            {
                log.Error("产生图片出现错误", e);
                throw e;
            }
        }

        public string GetDoc(string no, string title, string context, string grade)
        {
            log.DebugFormat("生成文档字帖，No：{0} Title：{1} Context：{2} Grade：{3}", no, title, context, grade);
            strNo = no;
            strTitle = title;
            strContext = context;
            string path1 = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "Image", MODELFILENAME);
            baseImage = new Bitmap(path1);
            baseGraphics = Graphics.FromImage(baseImage);
            if (strContext.Length > 16)
            {
                strContext = strContext.Substring(0, 16);
            }

            DrawHeader(grade);
            DrawTitle();
            DrawContext();
            string outputfile = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot"
                , "output"
                , string.Format("{0}.png", DateTime.Now.ToString("yyyyMMddHHmmss")));
            new Bitmap(baseImage).Save(outputfile);
            string docfile = ConvertToDocx(outputfile);

            ////////////////////////////////////////////////////////////////
            FileInfo fi = new FileInfo(docfile);
            FileStream fs = System.IO.File.OpenRead(docfile);
            byte[] data = new byte[fs.Length];
            fs.Read(data, 0, (int)fs.Length);
            string url = string.Format("{0}://{1}{2}{3}{4}"
                    , Request.Scheme
                    , Request.Host
                    , Request.PathBase
                    , "/output/"
                    , fi.Name);
            return url;
        }

        private void DrawTitle()
        {
            SolidBrush brush = new SolidBrush(COLOR_BLACK);
            int totallength = strTitle.Trim().Length * 326 + (1674 - 1220);
            int left = (4960 - totallength) / 2;

            Font numberfont = new Font(NUMBER_FONTFAMILY, 27.5F);
            LOCATION_TITLE_1.X = left;
            LOCATION_TITLE_2.X = (1674 - 1220) + left;
            baseGraphics.DrawString(strNo.Trim(), numberfont, brush, LOCATION_TITLE_1);

            Font chinesefont = new Font(CHINESE_FONTFAMILY, 27.5F);

            for (int i = 0; i < strTitle.Trim().Length; i++)
            {
                baseGraphics.DrawString(string.Format("{0}", strTitle[i])
                    , chinesefont
                    , brush
                    , new Point(LOCATION_TITLE_2.X + i * 326, LOCATION_TITLE_2.Y));
            }
        }

        private void DrawContext()
        {
            SolidBrush blackbrush = new SolidBrush(COLOR_BLACK);
            SolidBrush greybrush = new SolidBrush(COLOR_GREY);

            Font chinesefont = new Font(CHINESE_FONTFAMILY, 27.5F);

            //第一列
            for (int i = 0; i < strContext.Trim().Length; i++)
            {
                baseGraphics.DrawString(string.Format("{0}", strContext[i])
                    , chinesefont
                    , blackbrush
                    , new Point(LOCATION_CONTEXT.X, LOCATION_CONTEXT.Y + i * GAP_CONTEXT.Y + y_edit[i]));
            }


            //第二列
            for (int i = 0; i < strContext.Trim().Length; i++)
            {
                baseGraphics.DrawString(string.Format("{0}", strContext[i])
                    , chinesefont
                    , greybrush
                    , new Point(LOCATION_CONTEXT.X + GAP_CONTEXT.X, LOCATION_CONTEXT.Y + i * GAP_CONTEXT.Y + y_edit[i]));
            }

            //第三列
            for (int i = 0; i < strContext.Trim().Length; i++)
            {
                baseGraphics.DrawString(string.Format("{0}", strContext[i])
                    , chinesefont
                    , greybrush
                    , new Point(LOCATION_CONTEXT.X + GAP_CONTEXT.X * 2, LOCATION_CONTEXT.Y + i * GAP_CONTEXT.Y + y_edit[i]));
            }
        }

        private string ConvertToDocx(string imageFileName)
        {
            try
            {
                string _7zipExe = "C:\\Program Files\\7-Zip\\7z.exe";
                string basedir = Directory.GetCurrentDirectory();
                if (!Directory.Exists(basedir))
                {
                    Directory.CreateDirectory(basedir);
                }

                string _docmodelfilename = Path.Combine(basedir, "model.zip");

                string tempdirsubdir = Path.GetTempFileName();
                tempdirsubdir = tempdirsubdir.Substring(0, tempdirsubdir.IndexOf('.'));
                string _targetDir = Path.Combine(Path.GetTempPath(), tempdirsubdir);
                if (!Directory.Exists(_targetDir))
                {
                    Directory.CreateDirectory(_targetDir);
                }
                string cmd1 = string.Format("\"{0}\" x \"{1}\" -y -o\"{2}\""
                    , _7zipExe
                    , _docmodelfilename
                    , _targetDir);
                log.Info(cmd1);
                new CommandShell().RunCmd(cmd1);
                string targetimageFilename = Path.Combine(_targetDir, "word", "media", "image1.png");

                if (System.IO.File.Exists(targetimageFilename))
                {
                    System.IO.File.Delete(targetimageFilename);
                }
                log.InfoFormat("copy {0} {1}", imageFileName, targetimageFilename);
                System.IO.File.Copy(imageFileName, targetimageFilename);

                string outputDocxFile = imageFileName.Substring(0, imageFileName.LastIndexOf('.')) + ".docx";

                string cmd2 = string.Format("\"{0}\" a \"{1}\" \"{2}\" -tzip"
                    , _7zipExe
                    , outputDocxFile
                    , Path.Combine(_targetDir, "*"));
                log.Info(cmd2);
                new CommandShell().RunCmd(cmd2);

                string cmd3 = string.Format("rmdir /s /q \"{0}\"", _targetDir);
                log.Info(cmd3);
                new CommandShell().RunCmd(cmd3);
                return outputDocxFile;
            }
            catch (Exception e)
            {
                log.Error("转换文档到Docx出现问题", e);
                throw e;
            }
        }
    }
}
